/*
 * CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM.cpp
 *
 *  Created on: 2014. 1. 8.
 *      Author: jjaehuny
 */


#include "../../Command.h"

#include "../../User.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Static.h"
#include "../../NLogic/Stamina.h"
#include "../../NResource/Static.h"

#include "Common.h"

namespace ProjectZ { namespace NCommand {

static void SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(User * pUser, int16_t ack)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ack);
	pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_CREATE_PARTY_ROOM);
	pUser->Send(pAck);
}

void Command::CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(User * pUser, ::Network::Packet * pPacket)
{
	/*
	CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM		0x4004
	{
		u8 u8party_member_num;		/// min 1 , max 2 본인 제외한 값
	}

	SC_REQ_WORLD_BOSS_CREATE_PARTY_ROOM		0x4005
	{
		s16 sAck;						/// ACK_NOT_MAKE_PARTY 방 갯수 초과로 방을 만들 수 없음
		u32 u32room_number;
	}
	*/

	NLogic::Space * pWorld = pUser->GetSpace();
	if (NULL == pWorld)
	{
		DEBUGLOG("%s NULL == pWorld", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_NO_SPACE);
		return;
	}

	if (pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD)
	{
		DEBUGLOG("%s pWorld->GetData()._spaceType != NLogic::Space::SpaceType::WORLD", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_NO_SPACE);
		return;
	}

	if (pUser->GetEnumState() != User::EnumState::__NONE__)
	{
		DEBUGLOG("%s pUser->GetEnumState() != User::EnumState::__NONE__", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NResource::EventTimeResource * pEventTimeResource = NResource::Static::Instance().GetEventTime();
	if (NULL == pEventTimeResource)
	{
		DEBUGLOG("%s NULL == pEventTimeResource", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (false == pEventTimeResource->IsWorldBossEvent(pUser))
	{
		DEBUGLOG("%s false == pEventTimeResource->IsWorldBossEvent(pUser)", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_WORDBOSS_NOT_EVENT);
		return;
	}

	NLogic::Stamina * pStamina = pUser->GetStamina();
	if (NULL == pStamina)
	{
		DEBUGLOG("%s NULL == pStamina", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	if (true == pStamina->IsKeyLack(1))
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_NOT_ENOUGHT_STAMINA);
		return;
	}

/*	time_t currentSec;
	time(&currentSec);

	// 현재 스태미너가 최대라면 남은 회복 시간을 현재시간으로 설정
	if (pUser->GetCharacterInfo().event_stamina == STAMINA_MAX)
		pUser->GetCharacterInfo().recover_stamina_sec = currentSec;

	int staminaGap = pUser->GetCharacterInfo().event_stamina - 1;

	// 보유 스태미너가 부족한 경우
	if (staminaGap < 0)
	{
		DEBUGLOG("%s staminaGap < 0", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_NOT_ENOUGHT_STAMINA);
		return;
	}*/

	NResource::WorldBoss * pWorldBossResource = NResource::Static::Instance().GetWorldBossResource();
	if (NULL == pWorldBossResource)
	{
		DEBUGLOG("%s NULL == pWorldBossResource", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Static::WORLDBOSSROOMTREE & worldBossRoomTree = NLogic::Static::Instance().GETWORLDBOSSROOMTREE();
	if (static_cast<int>(worldBossRoomTree.size()) >= MAX_WORLDBOSS_PARTY_ROOM)
	{
		DEBUGLOG("%s NLogic::Static::Instance().GETPARTYROOMTREE().size() > MAX_NEW_PARTY_ROOM", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_OVER_PARTY_ROOM_COUNT);
		return;
	}

	NLogic::Space * pWorldBossSpace = NLogic::Static::Instance().GETSPACEPOOL()->NEW();
	if (NULL == pWorldBossSpace)
	{
		DEBUGLOG("%s NULL == pNewPartyRoomSpace", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::IndexerWorldBoss * pIndexer = NLogic::Static::Instance().GETWORLDBOSSINDEXPOOL()->NEW();
	if (NULL == pIndexer)
	{
		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pWorldBossSpace);

		DEBUGLOG("%s NULL == pIndexer", __FUNCTION__);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	auto itr = worldBossRoomTree.find(pIndexer->GetIndex());
	if (itr != worldBossRoomTree.end())
	{
		DEBUGLOG("%s itr != worldBossRoomTree.end() index : %d", __FUNCTION__, pIndexer->GetIndex());

		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pWorldBossSpace);
		NLogic::Static::Instance().GETWORLDBOSSINDEXPOOL()->DEL(pIndexer);

		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	NLogic::Party * pParty = NLogic::Static::Instance().GETPARTYPOOL()->NEW();
	if (NULL == pParty)
	{
		DEBUGLOG("%s NULL == pParty", __FUNCTION__);

		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pWorldBossSpace);
		NLogic::Static::Instance().GETWORLDBOSSINDEXPOOL()->DEL(pIndexer);

		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);
		return;
	}

	PREPARE_PACKET;

	uint8_t u8party_member_num = 0;

	* pPacket >> u8party_member_num;

	if (0 > u8party_member_num || u8party_member_num > 2)
	{
		DEBUGLOG("%s 0 > u8party_member_num || u8party_member_num > 2 : %d", __FUNCTION__, u8party_member_num);
		SendAck_CS_REQ_WORLD_BOSS_CREATE_PARTY_ROOM(pUser, ACK_UNKNOWN_ERROR);

		NLogic::Static::Instance().GETSPACEPOOL()->DEL(pWorldBossSpace);
		NLogic::Static::Instance().GETWORLDBOSSINDEXPOOL()->DEL(pIndexer);
		NLogic::Static::Instance().GETPARTYPOOL()->DEL(pParty);

		return;
	}

	pWorld->LeaveUser(pUser);

	pParty->Open(pUser);

	NLogic::Space::Data clsData;
	clsData._maxUser = u8party_member_num;
	clsData._table_id = pWorldBossResource->GetData().u16map_id;
	clsData._difficulty = 0;
	clsData._spaceType = NLogic::Space::SpaceType::WORLDBOSS_PARTY;
	clsData._boss_tid = pWorldBossResource->GetData().u16boss_tid1;

	pWorldBossSpace->Open(pUser, clsData);
	pWorldBossSpace->SetIndexerWorldBoss(pIndexer);
	pWorldBossSpace->SetParty(pParty);

	pWorldBossSpace->EnterUser(pUser);

	pParty->AddInviteUserTree(pUser);
	pUser->SetEnumState(User::EnumState::ACCEPT_WAIT);

	worldBossRoomTree[pIndexer->GetIndex()] = pWorldBossSpace;

	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	* pAck << static_cast<int16_t>(ACK_OK);
	* pAck << static_cast<uint32_t>(pIndexer->GetIndex());
	pAck->MakePacket(CMD_SC_REQ_WORLD_BOSS_CREATE_PARTY_ROOM);
	pUser->Send(pAck);
	STRESSLOG("CMD_SC_REQ_WORLD_BOSS_CREATE_PARTY_ROOM ACK");

	SendWorldBossDetailInfo(pUser);

	pParty->SetState(NLogic::Party::State::WORLD_BOSS_WAIT);
}

} /*NCommand*/ } /*ProjectZ*/
